package com.ilink.groundservice.service.impl.AiX;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ilink.groundservice.entity.PO.AiX.AiXTag;
import com.ilink.groundservice.entity.PO.AiX.AiXTagConnect;
import com.ilink.groundservice.entity.VO.AiX.AiXActivityResponse;
import com.ilink.groundservice.mapper.AiX.AiXActivityMapper;
import com.ilink.groundservice.mapper.AiX.AiXTagConnectMapper;
import com.ilink.groundservice.mapper.AiX.AiXTagMapper;
import com.ilink.groundservice.service.AiX.AiXActivityService;
import com.ilink.groundservice.entity.PO.AiX.AiXActivity;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ilink.ilinkapi.dto.ground.AiX.AiXActivityInsertRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXActivityUpdateRequest;
import com.ilink.ilinkapi.dto.ground.AiX.AiXAreaFilterRequest;
import com.ilink.ilinkcommon.domain.R;
import com.ilink.ilinkcommon.service.oss.MinioService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
import com.ilink.ilinkcommon.utils.SnowflakeIdGenerator;
import org.springframework.web.multipart.MultipartFile;
import java.util.Set;
import java.util.HashSet;

@Service
@Slf4j
@RequiredArgsConstructor
public class AiXActivityServiceImpl implements AiXActivityService {

    private final AiXActivityMapper aiXActivityMapper;

    private final AiXTagMapper aiXTagMapper;

    private final AiXTagConnectMapper aiXTagConnectMapper;

    private final MinioService minioService;

    @Override
    public IPage<AiXActivityResponse> getActivities(AiXAreaFilterRequest request) {
        // 创建分页对象
        Page<AiXActivity> page = new Page<>(request.getPage(), request.getSize());

        // 构建查询条件
        LambdaQueryWrapper<AiXActivity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(request.getAreaId() != null, AiXActivity::getAreaId, request.getAreaId());
        if (request.getTag() != null && !request.getTag().isEmpty()) {
            List<Long> activityIdsWithTag = aiXTagConnectMapper.selectList(
                new LambdaQueryWrapper<AiXTagConnect>().eq(AiXTagConnect::getTagId, 
                    aiXTagMapper.selectOne(new LambdaQueryWrapper<AiXTag>().eq(AiXTag::getTagName, request.getTag()).last("LIMIT 1")).getTagId())
                ).stream().map(AiXTagConnect::getConnectTableKey).collect(Collectors.toList());

            if (!activityIdsWithTag.isEmpty()) {
                queryWrapper.in(AiXActivity::getActivityId, activityIdsWithTag);
            } else {
                return new Page<>(request.getPage(), request.getSize()); // 如果没有匹配的标签，返回空结果
            }
        }

        if (!request.getKeyword().isEmpty()) {
            queryWrapper.and(wrapper ->
                wrapper.like(AiXActivity::getActivityTitle, request.getKeyword())
                    .or().like(AiXActivity::getIntroduction, request.getKeyword())
                    .or().like(AiXActivity::getAuthors, request.getKeyword())
            );
        }

        // 执行查询
        IPage<AiXActivity> activityPage = aiXActivityMapper.selectPage(page, queryWrapper);

        // 拼接响应
        List<AiXActivityResponse> responseList = activityPage.getRecords().stream()
            .map(activity -> {
                AiXActivityResponse response = new AiXActivityResponse();
                response.setActivityId(activity.getActivityId());
                String imagePath = minioService.getBucketFileUrl("dataset-square-migrate",activity.getCoverUrl());
                if(imagePath == null){
                    log.error("活动封面未找到"+activity.getCoverUrl());
                    return null;
                }
                response.setCoverUrl(imagePath);
                response.setActivityTitle(activity.getActivityTitle());
                response.setIntroduction(activity.getIntroduction());
                response.setAuthors(activity.getAuthors());
                response.setAreaId(activity.getAreaId());
                response.setTargetUrl(activity.getTargetUrl());
                
                // 获取活动标签并转换为字符串列表
                List<AiXTagConnect> tagConnects = aiXTagConnectMapper.selectList(new LambdaQueryWrapper<AiXTagConnect>().eq(AiXTagConnect::getConnectTableKey, activity.getActivityId()));
                List<String> tags = tagConnects.stream()
                    .map(tagConnect -> aiXTagMapper.selectById(tagConnect.getTagId()).getTagName())
                    .collect(Collectors.toList());
                response.setTags(tags); // 设置标签列表
                
                return response;
            })
            .collect(Collectors.toList());

        // 创建分页响应
        Page<AiXActivityResponse> responsePage = new Page<>(activityPage.getCurrent(), activityPage.getSize(), activityPage.getTotal());
        responsePage.setRecords(responseList);

        return responsePage;
    }

    @Override
    @Transactional
    public R insertActivity(AiXActivityInsertRequest request) {
        SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);
        Long activityId = idGenerator.nextId(); // 生成 activityId
        AiXActivity activity = new AiXActivity();
        activity.setActivityId(activityId);
        activity.setActivityTitle(request.getActivityTitle());
        activity.setIntroduction(request.getIntroduction());
        activity.setAuthors(request.getAuthors());
        activity.setAreaId(request.getAreaId());
        activity.setTargetUrl(request.getTargetUrl());

        // 上传封面图片到 OSS
        String objectName = "area/"+request.getAreaId()+"/activity/"+activityId+ getFileExtension(request.getCoverImage().getOriginalFilename());

        boolean isUploaded = minioService.uploadBucketFile(request.getCoverImage(), "dataset-square-migrate", objectName);
        if (!isUploaded) {
            return R.error("活动封面上传失败");
        }
        activity.setCoverUrl(objectName);

        aiXActivityMapper.insert(activity); // 插入活动

        // 插入标签
        if (request.getTags() != null) {
            handleTags(request.getTags(), activityId); // 调用提取的标签处理方法
        }
        return R.ok("活动插入成功");
    }

    @Override
    @Transactional
    public R updateActivity(AiXActivityUpdateRequest request) {
        // 生成新的 activityId
        Long activityId = request.getActivityId();

        // 创建活动对象并设置所有字段
        AiXActivity activity = new AiXActivity();
        activity.setActivityId(activityId);
        activity.setActivityTitle(request.getActivityTitle());
        activity.setIntroduction(request.getIntroduction());
        activity.setAuthors(request.getAuthors());
        activity.setAreaId(request.getAreaId());
        activity.setTargetUrl(request.getTargetUrl());

        // 更新活动
        aiXActivityMapper.updateById(activity);

        // 删除当前活动的所有标签
        aiXTagConnectMapper.delete(new LambdaQueryWrapper<AiXTagConnect>()
            .eq(AiXTagConnect::getConnectTableKey, activityId)
            .eq(AiXTagConnect::getConnectTable, "ai_x_activity"));

        // 处理新的标签
        if (request.getTags() != null) {
            handleTags(request.getTags(), activityId); // 调用提取的标签处理方法
        }

        return R.ok("活动更新成功");
    }

    @Override
    @Transactional
    public R updateActivityCover(MultipartFile file, Long activityId, Long areaId) {
        String objectName = "area/" + areaId + "/activity/" + activityId + getFileExtension(file.getOriginalFilename());
        boolean isUploaded = minioService.uploadBucketFile(file, "dataset-square-migrate", objectName);
        if (!isUploaded) {
            return R.error("活动封面更新失败");
        }
        // 查询活动对象
        AiXActivity activity = aiXActivityMapper.selectById(activityId);
        if (activity == null) {
            return R.error("活动未找到");
        }
        // 更新封面 URL
        activity.setCoverUrl(objectName);
        aiXActivityMapper.updateById(activity);
        return R.ok("活动封面更新成功");
    }

    @Override
    @Transactional
    public void deleteActivity(Long activityId) {
        try {
            AiXActivity activity = aiXActivityMapper.selectById(activityId);
            if (activity != null) {
                String coverUrl = activity.getCoverUrl();
                // 查找最后一个斜杠的位置
                int lastSlashIndex = coverUrl.lastIndexOf('/');
                // 使用substring方法进行拆分
                String directory = coverUrl.substring(0, lastSlashIndex + 1);
                String fileName = coverUrl.substring(lastSlashIndex + 1);
                boolean isDeleted = minioService.deleteBucketFile("dataset-square-migrate",directory, fileName);
                if (!isDeleted) {
                    log.error("删除OSS对象失败，活动ID: {}", activityId);
                }
                
                // 删除与活动相关的标签连接记录
                aiXTagConnectMapper.delete(new LambdaQueryWrapper<AiXTagConnect>()
                    .eq(AiXTagConnect::getConnectTableKey, activityId)
                    .eq(AiXTagConnect::getConnectTable, "ai_x_activity"));
            }
            // 删除数据库条目
            aiXActivityMapper.deleteById(activityId);
        } catch (Exception e) {
            log.error("删除活动失败，活动ID: {}", activityId, e);
            throw e;
        }
    }

    @Override
    public AiXActivityResponse getActivity(Long activityId) {
        AiXActivity activity = aiXActivityMapper.selectById(activityId);
        // 使用 AiXTagConnect 获取标签
        List<AiXTagConnect> tagConnects = aiXTagConnectMapper.selectList(
            new LambdaQueryWrapper<AiXTagConnect>()
                .eq(AiXTagConnect::getConnectTableKey, activityId)
                .eq(AiXTagConnect::getConnectTable, "ai_x_activity")
        );

        List<AiXTag> tags = tagConnects.stream()
            .map(tagConnect -> aiXTagMapper.selectById(tagConnect.getTagId()))
            .collect(Collectors.toList());

        AiXActivityResponse response = new AiXActivityResponse();
        response.setActivityId(activity.getActivityId());
        String imagePath = minioService.getBucketFileUrl("dataset-square-migrate", activity.getCoverUrl());
        if (imagePath == null) {
            log.error("活动封面未找到" + activity.getCoverUrl());
            return null;
        }
        response.setCoverUrl(imagePath);
        response.setActivityTitle(activity.getActivityTitle());
        response.setIntroduction(activity.getIntroduction());
        response.setAuthors(activity.getAuthors());
        response.setAreaId(activity.getAreaId());
        response.setTargetUrl(activity.getTargetUrl());
        response.setTags(tags.stream().map(AiXTag::getTagName).collect(Collectors.toList()));

        return response;
    }

    // 获取活动最常用的8个标签
    @Override
    public List<String> getActivityTags(Long areaId) {
        return aiXTagConnectMapper.getActivityTags(areaId, 8);
    }


    private void handleTags(List<String> tags, Long activityId) {
        for (String tag : tags) {
            // 检查标签是否已存在
            AiXTag existingTag = aiXTagMapper.selectOne(new LambdaQueryWrapper<AiXTag>().eq(AiXTag::getTagName, tag).last("LIMIT 1"));
            Long tagId;
            if (existingTag == null) {
                // 标签不存在，生成随机ID并插入新标签
                tagId = new SnowflakeIdGenerator(1, 1).nextId();
                AiXTag newTag = new AiXTag();
                newTag.setTagId(tagId);
                newTag.setTagName(tag);
                aiXTagMapper.insert(newTag); // 插入新标签
            } else {
                // 标签已存在，使用现有的tagId
                tagId = existingTag.getTagId();
            }

            // 在连接表中插入关联
            AiXTagConnect tagConnect = new AiXTagConnect();
            tagConnect.setConnectId(new SnowflakeIdGenerator(1, 1).nextId()); // 生成连接表主键
            tagConnect.setConnectTable("ai_x_activity");
            tagConnect.setConnectTableKey(activityId);
            tagConnect.setTagId(tagId);
            aiXTagConnectMapper.insert(tagConnect); // 插入关联
        }
    }

    private String getFileExtension(String fileName) {
        if (fileName == null) {
            return "";
        }
        int dotIndex = fileName.lastIndexOf('.');
        return dotIndex == -1 ? "" : fileName.substring(dotIndex);
    }

}
